/*********************************************************************&
 *
 *  MODULE: GDOC.CPP
 *  AUTHOR: BRIAN M. WORKMAN
 *  START DATE: 3/3/2006 9:19:09 PM
 *
 **********************************************************************/

#include "gdoc.h"

GDoc::GDoc(QWidget *parent) {
    setTextIndent(0);
    setWrapColumn(79);
    setCheckForDot(false);
    m_pad.fill(QChar(32), 4);
    document()->setModified(false);
    setTabChangesFocus(false);
    setAcceptRichText(false);
    brushtype = Qt::Dense4Pattern;
    m_parent = parent;
}

void GDoc::keyPressEvent( QKeyEvent *e) {

    if(e->key() == Qt::Key_Tab && (e->modifiers() == Qt::NoModifier)) {
        insertPlainText(pad());
        e->accept();
        return ;
    } else if (e->key() == Qt::Key_Return) {
        // Handle column margining
    } else if (e->key() == Qt::Key_C && (e->modifiers() == 
        Qt::ControlModifier)) {
        copy();
        e->accept();
        return ;  
    } else if (e->key() == Qt::Key_V && (e->modifiers() ==
        Qt::ControlModifier)) {
        paste();
        e->accept();
        return ;
    } else if (e->key() == Qt::Key_Escape) {
        e->accept();
        return ;
    }
    QTextEdit::keyPressEvent(e);
}

bool GDoc::dirty() const {
    return document()->isModified();
}

void GDoc::setFont(QFont font) {
    document()->setDefaultFont(font);
    //QFontMetrics fm(document->defaultFont());
    //m_fm = fm;
    m_fm = new QFontMetrics(font);
}

QFont GDoc::font() const {
    return document()->defaultFont();
}

void GDoc::paintEvent ( QPaintEvent *e ) {
    QTextEdit::paintEvent(e);
    if(m_mudfriendly) {
        QPalette pal;
        QPainter p(viewport());
        QBrush b(brushtype);
        m_gutter_x = m_fm->maxWidth() * (m_wrap+1);
        QRect r(m_gutter_x, 0, viewport()->width(), viewport()->height());
        p.fillRect(r, pal.color(pal.currentColorGroup(), QPalette::Window));
        p.drawLine(m_gutter_x, 0, m_gutter_x, viewport()->height());
    }
}

void GDoc::mousePressEvent (QMouseEvent *e) {
#ifndef Q_WS_X11
    if(e->button() == Qt::MidButton) {
        paste();
    }
#endif
    QTextEdit::mousePressEvent(e);
}

QString GDoc::pad() const {
    return m_pad;
}

void GDoc::setPad(QString s) {
    m_pad = s;
}

void GDoc::setText(QString text) {
    setPlainText(text);
}

QString GDoc::text() const {
    return toPlainText();
}

void GDoc::copy() {
    QTextEdit::copy();
    QClipboard *clip = QApplication::clipboard();
   
    int RIGHT = m_wrap - m_indent;
    QString INDENT;
    INDENT.fill(QChar(32), m_indent);
    QMimeData *mime = new QMimeData();
    mime->setText(clip->text());
    clip->setMimeData(mime);

    if(mudFriendly()) {
        QString work = clip->text().trimmed();
        if(work.length() <= RIGHT) {
            clip->setText(INDENT + work);
            return ;
        }
        QStringList blocks = work.split("\n");
        bool done = false;
        for(int i  = 0; i < blocks.count(); i++) {
            int left = 0;
            int right = m_wrap;
            QStringList inner;
            if(blocks[i].length() <= RIGHT) {
                blocks[i] = INDENT + blocks[i];
                continue;

            }
            do {
                QString sec = blocks[i].mid(left, right);
                int pos = sec.lastIndexOf(QChar(32));
                if(pos == -1) {
                    inner.append(INDENT + sec);
                    blocks[i].remove(0,RIGHT);
                } else {
                    inner.append(INDENT + sec.mid(0,pos));
                    blocks[i].remove(0,pos+1);
                }
                if(blocks[i].length() < RIGHT) {
                    inner.append(INDENT + blocks[i]);
                    done = true;
                }
            } while ( !done );
            blocks[i] = inner.join("\n");
            done = false;
        }
        work = blocks.join("\n");
        if(m_dot) {
            QStringList arr = work.split("\n");
            arr[0].remove(0, INDENT.length());
            arr[arr.size()-1].remove(0, INDENT.length());
            work = arr.join("\n");
        }
        clip->setText(work);
    }
}

void GDoc::paste() {
    QClipboard *clip = QApplication::clipboard();

    if(mudFriendly()) {
        QString resultats = clip->text();
        bool warn = (resultats.indexOf(QChar(9)) == -1 ? false : true);
        if(warn) {
            QString fill;
            fill.fill(QChar(32), 4);
            resultats.replace(QChar(9), fill);         
        }
    }

    QTextEdit::paste(); 
}

bool GDoc::mudFriendly() const {
    return m_mudfriendly;
}

void GDoc::setMudFriendly(bool yn) {
    m_mudfriendly = yn;
    if (yn) {
        setLineWrapMode(GDoc::FixedColumnWidth);
        setWordWrapMode(QTextOption::WrapAnywhere);
    } else {
        setLineWrapMode(GDoc::WidgetWidth);
        setWordWrapMode(QTextOption::WrapAnywhere);        
    }
}

void GDoc::setWrapColumn(int i) {
    m_wrap = i;
    setLineWrapColumnOrWidth(m_wrap);
}

int GDoc::wrapColumn() const {
    return m_wrap;
}
void GDoc::setTextIndent(int i) {
    m_indent = i;
}
int GDoc::textIndent() const {
    return m_indent;
}

bool GDoc::checkForDot() const {
    return m_dot;
}
void GDoc::setCheckForDot(bool yn) {
    m_dot = yn;
}
